package com.kystar.muxplayer;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Size;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.kystar.muxplayer.base.Strings;
import com.kystar.muxplayer.selfview.MyEditText;


import java.util.ArrayList;
import java.util.List;

/**
 * UI Helper
 *
 * Created by zhusheng on 2018-01-20.
 */

public class Helper {
   // private static Log log = new Log("helper");
    private static Toast toast = null;

    public static void onClick(View view, View.OnClickListener l) {
        view.setOnClickListener(l);
    }

    public static void onClick(View view, int itemId, View.OnClickListener l) {
        view.findViewById(itemId).setOnClickListener(l);
    }

    public static int getColor(int resId) {
        return BaseApp.mResources.getColor(resId);
    }

    public static float getFontSize(int resId) {
        return BaseApp.mResources.getDimension(resId);
    }

    public static float getDimension(int resId) {
        return BaseApp.mResources.getDimension(resId);
    }

    public static void show(String fmt, Object... args) {
        if (toast != null) {
            toast.cancel();
        }
        toast = com.kystar.muxplayer.ui.Toast.show(String.format(fmt, args));

    }

//    public static Object getField(Object obj, String path){
//        try {
//            String[] parts = path.split("/");
//            for (int i = 0; i < parts.length && obj != null; i++) {
//                String field = parts[i];
//                Class clz = obj.getClass();
//
//                int dotIndex = field.lastIndexOf('.');
//                if (dotIndex > 0) {
//                    clz = Class.forName(field.substring(0,dotIndex));
//                    field = field.substring(dotIndex+1);
//                }
//
//                obj = FieldUtils.getField(clz, field, true).get(obj);
//            }
//            return obj;
//        } catch (ReflectiveOperationException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }

    public static Spinner setupSpinner(Spinner spinner, int resID, String[] items) {
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(spinner.getContext(),
                resID, android.R.id.text1, items){
            @Override
            public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                if( parent != null) {
                    hideSystemUI(parent);
                }
                return super.getDropDownView(position, convertView, parent);
            }
        };
        adapter.setDropDownViewResource(R.layout.spinner_source_dropdown);
        spinner.setAdapter(adapter);
        return spinner;
    }

    public static int[] measureWrapContent(View view) {
        int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        view.measure(spec, spec);
        return new int[]{view.getMeasuredWidth(), view.getMeasuredHeight()};
    }

//    public static PopupWindow popupSeekBar(View anchor) {
//        return popupSeekBar(anchor, false, 128, null);
//    }

//    public static PopupWindow popupSeekBar(View anchor, boolean above, int value,
//                                           ColorSeekBar.OnChangeListener onChange) {
//        View popupSeekBar = View.inflate(anchor.getContext(), R.layout.popup_seekbar, null);
//        ColorSeekBar seekBar = popupSeekBar.findViewById(R.id.color_seek_bar);
//        seekBar.setValue(value);
//        seekBar.setOnChangListener(onChange);
//        hideSystemUI(popupSeekBar);
//        return showDropDownWindow(anchor, popupSeekBar, above, null);
//    }

//    public static ListView popupList(View pipType, ListAdapter adapter, int gravity) {
//        ListView listView = new ListView(pipType.getContext());
//        listView.setAdapter(adapter);
//        showDropDownWindow(pipType, listView, gravity);
//        return listView;
//    }

    public static PopupWindow showDropDownWindow(View anchor, View content, boolean above,
                                                 PopupWindow.OnDismissListener onDismiss) {
        int offset = 0;
        if (above) {
            int[] size= measureWrapContent(content);
            offset = -(anchor.getMeasuredHeight() + size[1]);
        }
        PopupWindow popupWindow = new PopupWindow(content,
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));
        popupWindow.setOutsideTouchable(false);
        popupWindow.setFocusable(true);
        popupWindow.showAsDropDown(anchor, 0, offset);
        popupWindow.setOnDismissListener(onDismiss);
        return popupWindow;
    }

    // ----------------------------------
    // view
    public static void hideSystemUI(Window window) {
        hideSystemUI(window.getDecorView());
    }
    public static void hideSystemUI(View view) {
        view.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                        | View.SYSTEM_UI_FLAG_IMMERSIVE);
    }
    public static void showSystemUI(Window window) {
        window.getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }

    // ----------------------------------
    // view

    public interface Consumer<V> {
        void apply(V v);
    }

    public interface Predicate<V> {
        boolean apply(V v);
    }

    public static void eachChild(View view, Consumer<View> consumer) {
        if (view == null || !(view instanceof ViewGroup)) {
            return;
        }
        ViewGroup vg = (ViewGroup) view;
        for (int i = 0; i <vg.getChildCount(); i++) {
            consumer.apply(vg.getChildAt(i));
        }
    }

    public static View firstChild(View view, Predicate<View> predicate) {
        if (view == null || !(view instanceof ViewGroup)) {
            return null;
        }
        ViewGroup vg = (ViewGroup) view;
        for (int i = 0; i <vg.getChildCount(); i++) {
            if(predicate.apply(vg.getChildAt(i))) {
                return vg.getChildAt(i);
            }
        }
        return null;
    }


    public static List<View> getChildren(View view) {
        List<View> views = new ArrayList<>();
        eachChild(view, child -> views.add(child));
        return views;
    }

    public static void each(List<View> views, Consumer<View> consumer){
        for (View view:views) {
            consumer.apply(view);
        }
    }

    public static List<View> filter(List<View> views, Predicate<View> predicate) {
        List<View> res = new ArrayList<>();
        for (View view:views) {
            if(predicate.apply(view)) {
                res.add(view);
            }
        }
        return res;
    }

    public static boolean hasTag(View view) {
        return view.getTag() != null;
    }

    public static <T extends View> T getChildView(View view, int index) {
        if (view != null) {
            return (T) ((ViewGroup) view).getChildAt(index);
        } else {
          //  log.debug("getChildView of null");
        }
        return null;
    }

    public static void setChildTextColor(View v, int index, boolean highlight) {
        if (v == null) {
//            log.debug("setChildTextColor of null");
            return;
        }

        if (index > 0) {
            setTextColor(getChildView(v, index), highlight);
            return;
        }

        if (v instanceof TextView) {
            setTextColor((TextView) v, highlight);
            return;
        }

        if(v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                v = vg.getChildAt(i);
                if (v instanceof TextView) {
                    setTextColor((TextView)v, highlight);
                }
            }
        } else {
          //  log.debug("setChildTextColor of none ViewGroup ");
        }
    }

    public static void setTextColor(TextView v, boolean highlight) {
        if (v != null) {
            if(highlight) {
                v.setTextColor(getColor(R.color.main_font_color_highlight));
            } else {
                v.setTextColor(getColor(R.color.main_font_color_normal));
            }
        } else {
           // log.debug("setTextColor of null");
        }
    }

    public static void animalTextColor(View view) {
        TextView textView = (TextView) view;
        setTextColor(textView, true);
        textView.postDelayed(()->setTextColor(textView, false), 500);
    }

    public static void showView(View view) {
        view.setVisibility(View.VISIBLE);
    }

    public static void hideView(View view) {
        view.setVisibility(View.GONE);
    }

    public static void setText(View parent, int textViewId, String value) {
        ((TextView)parent.findViewById(textViewId)).setText(value);
    }

    // ----------------------------------
    public static boolean ok(Boolean v, Exception ex) {
        if(ex == null && v != null && v) {
            return true;
        }
        show("操作失败");
        return false;
    }
    // ----------------------------------

    public interface TextChangeListener {
        void onTextChanged(Editable s);
    }

    public static void setTextChangeListener(EditText editText, TextChangeListener listener) {
        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                listener.onTextChanged(s);
            }
        });
    }

    // ----------------------------------

    public static String getTag(View view) {
        if(view != null && view.getTag() != null) {
            return view.getTag().toString();
        }
        return "";
    }

    public static int getTagInt(View view, int trimStart){
        if(view != null && view.getTag() != null) {
            String tag = view.getTag().toString();
            return Integer.parseInt(tag.substring(trimStart));
        }
        return -1;
    }

    public static int getTagInt(View view, int trimStart, int trimEnd){
        if(view != null && view.getTag() != null) {
            String tag = view.getTag().toString();
            return Integer.parseInt(tag.substring(trimStart, tag.length() - trimEnd));
        }
        return -1;
    }

    public static int[] getTagInts(View view, String sep) {
        if(view != null && view.getTag() != null) {
            return Strings.toInts(view.getTag().toString(), sep);
        }
        return null;
    }

    public static Size parseSize(MyEditText sizeH, MyEditText sizeV) {
        int width = Helper.parseSize(sizeH.getText().toString(), "水平大小", 0, 4000);
        int height = Helper.parseSize(sizeV.getText().toString(), "垂直大小", 0, 2000);
        return new Size(width, height);
    }

    public static int parseSize(String text, String msg, int min, int max) {
        int value;
        try{
            value = Integer.parseInt(text);
        } catch (Exception ex) {
            throw new IllegalArgumentException("非法数字", ex);
        }
        if (value<min || value>max) {
            throw new IllegalArgumentException(msg + "不能超出范围(" + min + "," + max + ")");
        }
        return value;
    }

    // ----------------------------------

    public static Bitmap createBitmap(float width, float height) {
        return Bitmap.createBitmap(Math.round(width), Math.round(height), Bitmap.Config.ARGB_8888);
    }

    // ----------------------------------

    public static void drawRect(Paint paint, Canvas canvas, RectF rect, float border) {
        float d = border/2;
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(border);
        canvas.drawRect(rect.left+d, rect.top+d, rect.right-d, rect.bottom-d, paint);
    }

    public static void drawColorRect(Paint paint, Canvas canvas, RectF rect, int color, float border) {
        paint.setColor(color);
        drawRect(paint, canvas, rect, border);
    }

    public static void fillColorRect(Paint paint, Canvas canvas, RectF rect, int color) {
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(color);
        paint.setStrokeWidth(0);
        canvas.drawRect(rect, paint);
    }

    public static RectF enlarge(RectF rect, float d) {
        rect.left -= d;
        rect.top -= d;
        rect.right += d;
        rect.bottom += d;
        return rect;
    }

    public static RectF enlarge(RectF rect, RectF out, float d) {
        out.set(rect);
        return enlarge(out, d);
    }

    public static RectF shrink(RectF rect,float d) {
        return enlarge(rect, -d);
    }

    public static RectF shrink(RectF rect, RectF out, float d) {
        out.set(rect);
        return enlarge(out, -d);
    }

    public static Rect rect(RectF rc) {
        return new Rect(
                Math.round(rc.left),
                Math.round(rc.top),
                Math.round(rc.right),
                Math.round(rc.bottom)
        );
    }

    public static RectF rectF(int width, int height){
        return new RectF(0, 0, width, height);
    }

//    public static boolean isEmulator() {
//        String cpuInfo = IO.readAllString("/proc/cpuinfo");
//        return cpuInfo.contains("Intel") || cpuInfo.contains("Amd");
//    }
}
